<template>
  <div>
    <div
      v-if="type === 'card'"
      class="upload-card-components"
      :class="`${size} ${limit === 1 ? 'is-single' : ''}`"
    >
      <el-upload
        :action="uploadUrl"
        list-type="picture-card"
        :on-preview="onPreview"
        :on-success="onSuccess"
        :file-list="fileList"
        :on-remove="onRemove"
        :limit="limit"
        :multiple="multiple"
        :before-upload="beforeUpload"
        :http-request="uploadSectionFile"
        :on-progress="uploadVideoProcess"
      >
        <i class="el-icon-plus"></i>
      </el-upload>
    </div>
    <div v-if="type === 'btn'">
      <el-button type="primary" @click="updateVisible = true">{{
        fileList.length === 0 ? btnText : "重新上传"
      }}</el-button>
      <el-dialog
        class="main-dialog"
        title="选择文件"
        :visible.sync="updateVisible"
        :append-to-body="true"
        :modal-append-to-body="true"
        width="400px"
      >
        <div class="upload-btn-components">
          <el-upload
            :action="uploadUrl"
            drag
            :on-preview="onPreview"
            :on-success="onSuccess"
            :file-list="fileList"
            :on-remove="onRemove"
            :limit="limit"
            :multiple="multiple"
            :before-upload="beforeUpload"
            :http-request="uploadSectionFile"
            :on-progress="uploadVideoProcess"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <div class="el-upload__tip" slot="tip" style="width: 360px">
              {{ tip === "" ? `最多可上传${limit}个文件` : tip }}
            </div>
          </el-upload>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="updateVisible = false"
            >确 定</el-button
          >
        </span>
      </el-dialog>
    </div>
    <el-upload
      v-if="type === 'btn-file'"
      :action="uploadUrl"
      :on-preview="onPreview"
      :on-success="onSuccess"
      :file-list="fileList"
      :on-remove="onRemove"
      :limit="limit"
      :multiple="multiple"
      :before-upload="beforeUpload"
      :http-request="uploadSectionFile"
      :on-progress="uploadVideoProcess"
    >
      <el-button type="primary">{{
        fileList.length === 0 ? btnText : "重新上传"
      }}</el-button>
      <div slot="tip" class="el-upload__tip" style="width: 360px">
        {{ tip === "" ? `最多可上传${limit}个文件` : tip }}
      </div>
    </el-upload>
    <ElImageViewer
      v-if="showViewer"
      :on-close="
        () => {
          this.showViewer = false;
        }
      "
      :url-list="[imgViewerPath]"
    />
  </div>
</template>
<script>
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
import { upDateFun } from "./composition";
import axios from "axios";

export default {
  // 单张图片上传时 绑定的是单个图片Object 多张图片上传时 绑定多张图片Object的数组
  // {
  //   name: 'xxx',
  //   type: 'png',
  //   size: '10000',
  //   url: 'xxxxx'
  // }
  model: {
    prop: "modelVal",
    event: "change",
  },
  props: {
    modelVal: {
      type: [Object, Array],
      default: () => {
        return null;
      },
    },
    // 图片上传路径
    uploadUrl: {
      type: String,
      default: "",
    },
    // 最大上传个数
    limit: {
      type: Number,
      default: 1,
    },
    // medium
    size: {
      type: String,
      default: "small",
    },
    // card: 卡片上传 btn: 按钮弹窗上传 btn-file: 按钮不带弹窗上传
    type: {
      type: String,
      default: "card",
    },
    // 按钮上传的文案
    btnText: {
      type: String,
      default: "上传文件",
    },
    // 上传提示
    tip: {
      type: String,
      default: "",
    },
    // 是否支持多选文件
    multiple: {
      type: Boolean,
      default: false,
    },
    // 允许的上传格式
    format: {
      type: Array,
      default: () => [],
    },
    // 文件大小的限制
    fileSize: {
      type: Number,
      default: 1048576 * 1024 * 2,
    },
    // 是否上传视频
    videos: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    ElImageViewer,
  },
  data() {
    return {
      showViewer: false,
      imgViewerPath: "",

      fileList: [],
      updateVisible: false,
    };
  },
  watch: {
    modelVal: {
      handler: function (val) {
        if (!val) {
          this.fileList = [];
        } else {
          if (this.limit === 1) {
            this.fileList = [val];
          } else {
            this.fileList = val;
          }
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    // 查看图片
    onPreview(file) {
      this.showViewer = true;
      this.imgViewerPath = file.url;
    },

    // 上传文件格式大小拦截
    beforeUpload(file) {
      if (this.format.length === 0) return true;

      const fileFormat = file.name.substring(file.name.lastIndexOf(".") + 1);
      const formatState = this.format.indexOf(fileFormat) > -1;
      if (!formatState) {
        this.$message({
          message: `只允许上传${this.format.join()}格式的文件，请重新选择！`,
          type: "warning",
        });
      }

      const fileSizeState = this.fileSize > file.size;
      if (!fileSizeState) {
        this.$message({
          message: "上传文件过大，请重新选择!",
          type: "warning",
        });
      }

      return formatState && fileSizeState;
    },

    // 自定义上传
    uploadSectionFile(params) {
      this.httpLoad(params);
    },

    async httpLoad(params) {
      const { file, onProgress, onSuccess } = params;

      // 获取红船云的key
      const signature = await upDateFun();

      // 获取腾讯云上传的key
      const {
        data: {
          data: {
            storageBucket,
            video: { storagePath, storageSignature },
            vodSessionKey,
          },
        },
      } = await axios.post(
        "https://vod2.qcloud.com/v3/index.php?Action=ApplyUploadUGC",
        {
          signature,
          videoName: file.name.split(".")[0],
          videoType: file.name.split(".")[1],
          videoSize: file.size,
        }
      );

      // 处理上传文件参数
      const form = new FormData();
      form.append("op", "upload");
      form.append("fileContent", file);
      form.append("insertOnly", 1);

      // 开始上传
      await axios({
        url: `http://cq.file.myqcloud.com/files/v2/10022853/${storageBucket}${storagePath}?sign=${encodeURIComponent(
          storageSignature
        )}`,
        method: "post",
        data: form,
        onUploadProgress: (progressEvent) => {
          const percent = (progressEvent.loaded / progressEvent.total) * 100;
          // 监听上传进度
          onProgress({ percent: percent });
        },
      });

      // 获取文件地址
      const {
        data: {
          data: {
            video: { url },
          },
        },
      } = await axios.post(
        "https://vod2.qcloud.com/v3/index.php?Action=CommitUploadUGC",
        {
          signature,
          vodSessionKey,
        }
      );

      // 上传成功回调
      onSuccess({ data: { url } });
    },

    uploadVideoProcess(event, file) {
      console.log(file.percentage.toFixed(0));
    },

    // 上传成功回调
    onSuccess(_, __, fileList) {
      this.update(fileList);
    },

    // 删除文件回调
    onRemove(_, fileList) {
      this.update(fileList);
    },

    // 数据处理
    update(val) {
      if (this.limit === 1) {
        const dataObj = val[0] || null;
        const result = dataObj
          ? {
              name: dataObj.name,
              type: dataObj.raw ? dataObj.raw.type : "",
              size: dataObj.size,
              baseUrl: process.env.VUE_APP_FILE_URL,
              url: dataObj.response
                ? process.env.VUE_APP_FILE_URL + dataObj.response.data.url
                : "",
              date: dataObj.raw ? dataObj.raw.lastModified : "",
              data: dataObj.response.data.url || "",
            }
          : null;
        this.$emit("update:modelValue", result);
        this.$emit("change", result);
      } else {
        const resultList = val.map((file) => {
          if (file.response) {
            return {
              name: file.name,
              type: file.raw ? file.raw.type : "",
              size: file.size,
              baseUrl: process.env.VUE_APP_FILE_URL,
              url: file.response ? file.response.data.url : "",
              date: file.raw ? file.raw.lastModified : "",
              data: file.response.data.url || "",
            };
          } else {
            return file;
          }
        });
        console.log(resultList);
        this.$emit("update:modelValue", resultList);
        this.$emit("change", resultList);
      }
    },
  },
};
</script>

<style lang="scss">
.upload-card-components {
  .el-upload--picture-card {
  }
}

.upload-btn-components {
  margin: 20px auto;
  display: flex;
  justify-content: center;
  .el-upload-list {
    .el-upload-list__item-name {
      width: 300px;
    }
  }
}

// 默认
.small {
  .el-upload--picture-card {
    width: 82px;
    height: 82px;
    line-height: 92px;
  }
  .el-upload-list__item {
    width: 82px;
    height: 82px;
  }
}

// 大号
.medium {
  .el-upload--picture-card {
    width: 132px;
    height: 132px;
    line-height: 142px;
    .el-upload-list__item {
      width: 132px;
      height: 132px;
    }
  }
}

// 单个上传
.is-single {
  overflow: hidden;
  width: 82px;
  height: 82px;
}
</style>
